﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NHibernate;
using NHibernate.Criterion;

using BOSS.Framework.Search;
using BOSS.Framework.Search.Context;
using BOSS.Domain.Customers;
using BOSS.Dao.Customers;     

namespace BOSS.Dao.NHibernate.Customers
{
    public class CustomerCardDao : EntityDao<CustomerCard, int>, ICustomerCardDao
    {

        #region ISearchSupport<CustomerCard> 成员

        public IList<CustomerCard> SelectBySearch(ISearchContext context, out int totalCount)
        {
            int count = 0;

            string cardholder = context.GetFilterTermValueAsString("Cardholder");
            string numberOrCardholder = context.GetFilterTermValueAsString("CardNumberOrCardholder");
            int? state = context.GetFilterTermValueAsInt32("State");

            IList<CustomerCard> customerCards = this.HibernateTemplate.ExecuteFind<CustomerCard>(delegate(ISession session)
            {
                ICriteria criteria = session.CreateCriteria(typeof(CustomerCard), "cc")
                                            .CreateAlias("cc.Cardholder", "ccc");

                if (!string.IsNullOrEmpty(cardholder))
                {
                    criteria.Add(Expression.Like("ccc.Name", cardholder, MatchMode.Anywhere));
                }
                if (!string.IsNullOrEmpty(numberOrCardholder))
                {
                    criteria.Add(Expression.Or(Expression.Like("cc.CardNumber", numberOrCardholder, MatchMode.Anywhere), Expression.Like("ccc.Name", numberOrCardholder, MatchMode.Anywhere)));
                }
                if (state != null)
                {
                    criteria.Add(Expression.Eq("cc.State", (CustomerCardState)state.Value));
                }

                count = criteria.SetProjection(Projections.Count("Id").SetDistinct()).UniqueResult<int>();
                if (count == 0)
                {
                    return new List<CustomerCard>();
                }

                criteria.SetProjection(new IProjection[] { null });
                criteria.SetResultTransformer(CriteriaSpecification.DistinctRootEntity);

                return criteria.SetFirstResult(context.PageSize * (context.PageIndex - 1))
                        .SetMaxResults(context.PageSize)
                        .List<CustomerCard>();
            });

            totalCount = count;
            return customerCards;
        }

        #endregion

        #region ICustomerCardDao 成员

        public CustomerCard FindByCardNumber(string cardNumber)
        {
            return this.HibernateTemplate.Find<CustomerCard>("from CustomerCard c where c.CardNumber = ?", cardNumber).FirstOrDefault();
        }

        #endregion
    }
}
